﻿//
// site.js
//
// the arbor.js website
//
(function ($) {
    // var trace = function(msg){
    //   if (typeof(window)=='undefined' || !window.console) return
    //   var len = arguments.length, args = [];
    //   for (var i=0; i<len; i++) args.push("arguments["+i+"]")
    //   eval("console.log("+args.join(",")+")")
    // }  

    var Renderer = function (elt) {
        var dom = $(elt)
        var canvas = dom.get(0)
        var ctx = canvas.getContext("2d");
        var gfx = arbor.Graphics(canvas)
        var sys = null

        var _vignette = null
        var selected = null,
        nearest = null,
        _mouseP = null;


        var that = {
            init: function (pSystem) {
                sys = pSystem
                sys.screen({ size: { width: dom.width(), height: dom.height() },
                    padding: [36, 60, 36, 60]
                })

                $(window).resize(that.resize)
                that.resize()
                that._initMouseHandling()

                if (document.referrer.match(/echolalia|atlas|halfviz/)) {
                    // if we got here by hitting the back button in one of the demos, 
                    // start with the demos section pre-selected
                    that.switchSection('demos')
                }
            },
            resize: function () {
                canvas.width = $(window).width()
                canvas.height = .75 * $(window).height()
                sys.screen({ size: { width: canvas.width, height: canvas.height} })
                _vignette = null
                that.redraw()
            },
            redraw: function () {
                gfx.clear()
                sys.eachEdge(function (edge, p1, p2) {
                    if (edge.source.data.alpha * edge.target.data.alpha == 0) return
                    gfx.line(p1, p2, { stroke: "#b2b19d", width: 2, alpha: edge.target.data.alpha })
                })


                sys.eachNode(function (node, pt) {
                    var w = Math.max(20, 20 + gfx.textWidth(node.name))
                    if (node.data.alpha === 0) return
                    if (node.data.shape == 'dot') {
                        if(node.name == 'user1'){
                          var $hiddenList = $('#hiddenList');
                          //alert($hiddenlist.val());
                          /*for each(var connection in $hiddenList.val()){
                            var friend = connection.id;
                            
                        }*/
                        }
                        /*if(node.name == 'user1'){
                            var $idHidden = $('#id-hidden1');
                            var img = new Image();
                            ctx.fillStyle = "#b2b19d";
                            ctx.fillRectR(pt.x - 55, pt.y - 55, 110, 110)
                            img.src = "https://graph.facebook.com/" + friend + "/picture?type=large";
                            ctx.drawImage(img, pt.x - 50, pt.y - 50, 100, 100)
                        }
                        else if(node.name == 'user2'){
                            var $idHidden = $('#id-hidden2');
                            var img = new Image();
                            ctx.fillStyle = "#b2b19d";
                            ctx.fillRectR(pt.x - 55, pt.y - 55, 110, 110)
                            img.src = "https://graph.facebook.com/" + $idHidden.val() + "/picture?type=large";
                            ctx.drawImage(img, pt.x - 50, pt.y - 50, 100, 100)
                        }
                        else if(node.name == 'user3'){
                            var $idHidden = $('#id-hidden3');
                            var img = new Image();
                            ctx.fillStyle = "#b2b19d";
                            ctx.fillRectR(pt.x - 55, pt.y - 55, 110, 110)
                            img.src = "https://graph.facebook.com/" + $idHidden.val() + "/picture?type=large";
                            ctx.drawImage(img, pt.x - 50, pt.y - 50, 100, 100)
                        }
                        else if(node.name == 'user4'){
                            var $idHidden = $('#id-hidden4');
                            var img = new Image();
                            ctx.fillStyle = "#b2b19d";
                            ctx.fillRectR(pt.x - 55, pt.y - 55, 110, 110)
                            img.src = "https://graph.facebook.com/" + $idHidden.val() + "/picture?type=large";
                            ctx.drawImage(img, pt.x - 50, pt.y - 50, 100, 100)
                        }
                        else if(node.name == 'user5'){
                            var $idHidden = $('#id-hidden5');
                            var img = new Image();
                            ctx.fillStyle = "#b2b19d";
                            ctx.fillRectR(pt.x - 55, pt.y - 55, 110, 110)
                            img.src = "https://graph.facebook.com/" + $idHidden.val() + "/picture?type=large";
                            ctx.drawImage(img, pt.x - 50, pt.y - 50, 100, 100)
                        }
                        else if(node.name == 'user6'){
                            var $idHidden = $('#id-hidden6');
                            var img = new Image();
                            ctx.fillStyle = "#b2b19d";
                            ctx.fillRectR(pt.x - 55, pt.y - 55, 110, 110)
                            img.src = "https://graph.facebook.com/" + $idHidden.val() + "/picture?type=large";
                            ctx.drawImage(img, pt.x - 50, pt.y - 50, 100, 100)
                        }*/
                       // else{
                            gfx.oval(pt.x - w / 2, pt.y - w / 2, w, w, { fill: node.data.color, alpha: node.data.alpha })
                            gfx.text(node.name, pt.x, pt.y + 7, { color: "white", align: "center", font: "Arial", size: 12 })
                            gfx.text(node.name, pt.x, pt.y + 7, { color: "white", align: "center", font: "Arial", size: 12 })
                        //}
                      }
                        else{//rectangles
                        /*if(node.name == 'name1'){
                            var $nameHidden = $('#name-hidden1');
                            var w = Math.max(20, 20 + gfx.textWidth($nameHidden.val()))
                            gfx.rect(pt.x - w / 2, pt.y - 8, w, 20, 4, { fill: node.data.color, alpha: node.data.alpha })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                        }
                        else if(node.name == 'name2'){
                            var $nameHidden = $('#name-hidden2');
                            var w = Math.max(20, 20 + gfx.textWidth($nameHidden.val()))
                            gfx.rect(pt.x - w / 2, pt.y - 8, w, 20, 4, { fill: node.data.color, alpha: node.data.alpha })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                        }
                        else if(node.name == 'name3'){
                            var $nameHidden = $('#name-hidden3');
                            var w = Math.max(20, 20 + gfx.textWidth($nameHidden.val()))
                            gfx.rect(pt.x - w / 2, pt.y - 8, w, 20, 4, { fill: node.data.color, alpha: node.data.alpha })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                        }
                        else if(node.name == 'name4'){
                            var $nameHidden = $('#name-hidden4');
                            var w = Math.max(20, 20 + gfx.textWidth($nameHidden.val()))
                            gfx.rect(pt.x - w / 2, pt.y - 8, w, 20, 4, { fill: node.data.color, alpha: node.data.alpha })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                        }
                        else if(node.name == 'name5'){
                            var $nameHidden = $('#name-hidden5');
                            var w = Math.max(20, 20 + gfx.textWidth($nameHidden.val()))
                            gfx.rect(pt.x - w / 2, pt.y - 8, w, 20, 4, { fill: node.data.color, alpha: node.data.alpha })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                        }
                        else if(node.name == 'name6'){
                            var $nameHidden = $('#name-hidden6');
                            var w = Math.max(20, 20 + gfx.textWidth($nameHidden.val()))
                            gfx.rect(pt.x - w / 2, pt.y - 8, w, 20, 4, { fill: node.data.color, alpha: node.data.alpha })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                            gfx.text($nameHidden.val(), pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                        }*/
                           // else{
                            gfx.rect(pt.x - w / 2, pt.y - 8, w, 20, 4, { fill: node.data.color, alpha: node.data.alpha })
                            gfx.text(node.name, pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                            gfx.text(node.name, pt.x, pt.y + 9, { color: "white", align: "center", font: "Arial", size: 12 })
                            //}
                        }
                })
                that._drawVignette()
            },

            _drawVignette: function () {
                var w = canvas.width
                var h = canvas.height
                var r = 20

                if (!_vignette) {
                    var top = ctx.createLinearGradient(0, 0, 0, r)
                    top.addColorStop(0, "#e0e0e0")
                    top.addColorStop(.7, "rgba(255,255,255,0)")

                    var bot = ctx.createLinearGradient(0, h - r, 0, h)
                    bot.addColorStop(0, "rgba(255,255,255,0)")
                    bot.addColorStop(1, "white")

                    _vignette = { top: top, bot: bot }
                }

                // top
                ctx.fillStyle = _vignette.top
                ctx.fillRect(0, 0, w, r)

                // bot
                ctx.fillStyle = _vignette.bot
                ctx.fillRect(0, h - r, w, r)
            },

            switchMode: function (e) {
                if (e.mode == 'hidden') {
                    dom.stop(true).fadeTo(e.dt, 0, function () {
                        if (sys) sys.stop()
                        $(this).hide()
                    })
                } else if (e.mode == 'visible') {
                    dom.stop(true).css('opacity', 0).show().fadeTo(e.dt, 1, function () {
                        that.resize()
                    })
                    if (sys) sys.start()
                }
            },

            switchSection: function (newSection) {
                var parent = sys.getEdgesFrom(newSection)[0].source
                var children = $.map(sys.getEdgesFrom(newSection), function (edge) {
                    return edge.target
                })

                sys.eachNode(function (node) {
                    if (node.data.shape == 'dot') return // skip all but leafnodes

                    var nowVisible = ($.inArray(node, children) >= 0)
                    var newAlpha = (nowVisible) ? 1 : 0
                    var dt = (nowVisible) ? .5 : .5
                    sys.tweenNode(node, dt, { alpha: newAlpha })

                    if (newAlpha == 1) {
                        node.p.x = parent.p.x + .05 * Math.random() - .025
                        node.p.y = parent.p.y + .05 * Math.random() - .025
                        node.tempMass = .001
                    }
                })
            },


            _initMouseHandling: function () {
                // no-nonsense drag and drop (thanks springy.js)
                selected = null;
                nearest = null;
                var dragged = null;
                var oldmass = 1

                var _section = null

                var handler = {
                    moved: function (e) {
                        var pos = $(canvas).offset();
                        _mouseP = arbor.Point(e.pageX - pos.left, e.pageY - pos.top)
                        nearest = sys.nearest(_mouseP);

                        if (!nearest.node) return false

                        if (nearest.node.data.shape != 'dot') {
                            selected = (nearest.distance < 50) ? nearest : null
                            if (selected) {
                                dom.addClass('linkable')
                                window.status = selected.node.data.link.replace(/^\//, "http://" + window.location.host + "/").replace(/^#/, '')
                            }
                            else {
                                dom.removeClass('linkable')
                                window.status = ''
                            }
                        } else if ($.inArray(nearest.node.name, ['arbor.js', 'code', 'docs', 'demos', 'user1', 'user2', 'user3', 'user4', 'user5', 'user6']) >= 0) {
                            if (nearest.node.name != _section) {
                                _section = nearest.node.name
                                that.switchSection(_section)
                            }
                            dom.removeClass('linkable')
                            window.status = ''
                        }

                        return false
                    },
                    clicked: function (e) {
                        var pos = $(canvas).offset();
                        _mouseP = arbor.Point(e.pageX - pos.left, e.pageY - pos.top)
                        nearest = dragged = sys.nearest(_mouseP);

                        if (nearest && selected && nearest.node === selected.node) {
                            var link = selected.node.data.link
                            if (link.match(/^#/)) {
                                $(that).trigger({ type: "navigate", path: link.substr(1) })
                            } else {
                                window.location = link
                            }
                            return false
                        }


                        if (dragged && dragged.node !== null) dragged.node.fixed = true

                        $(canvas).unbind('mousemove', handler.moved);
                        $(canvas).bind('mousemove', handler.dragged)
                        $(window).bind('mouseup', handler.dropped)

                        return false
                    },
                    dragged: function (e) {
                        var old_nearest = nearest && nearest.node._id
                        var pos = $(canvas).offset();
                        var s = arbor.Point(e.pageX - pos.left, e.pageY - pos.top)

                        if (!nearest) return
                        if (dragged !== null && dragged.node !== null) {
                            var p = sys.fromScreen(s)
                            dragged.node.p = p
                        }

                        return false
                    },

                    dropped: function (e) {
                        if (dragged === null || dragged.node === undefined) return
                        if (dragged.node !== null) dragged.node.fixed = false
                        dragged.node.tempMass = 1000
                        dragged = null;
                        // selected = null
                        $(canvas).unbind('mousemove', handler.dragged)
                        $(window).unbind('mouseup', handler.dropped)
                        $(canvas).bind('mousemove', handler.moved);
                        _mouseP = null
                        return false
                    }


                }

                $(canvas).mousedown(handler.clicked);
                $(canvas).mousemove(handler.moved);

            }
        }

        return that
    }


    var Nav = function (elt) {
        var dom = $(elt)

        var _path = null

        var that = {
            init: function () {
                $(window).bind('popstate', that.navigate)
                dom.find('> a').click(that.back)
                $('.more').one('click', that.more)

                $('#docs dl:not(.datastructure) dt').click(that.reveal)
                that.update()
                return that
            },
            more: function (e) {
                $(this).removeAttr('href').addClass('less').html('&nbsp;').siblings().fadeIn()
                $(this).next('h2').find('a').one('click', that.less)

                return false
            },
            less: function (e) {
                var more = $(this).closest('h2').prev('a')
                $(this).closest('h2').prev('a')
        .nextAll().fadeOut(function () {
            $(more).text('creation & use').removeClass('less').attr('href', '#')
        })
                $(this).closest('h2').prev('a').one('click', that.more)

                return false
            },
            reveal: function (e) {
                $(this).next('dd').fadeToggle('fast')
                return false
            },
            back: function () {
                _path = "/"
                if (window.history && window.history.pushState) {
                    window.history.pushState({ path: _path }, "", _path);
                }
                that.update()
                return false
            },
            navigate: function (e) {
                var oldpath = _path
                if (e.type == 'navigate') {
                    _path = e.path
                    if (window.history && window.history.pushState) {
                        window.history.pushState({ path: _path }, "", _path);
                    } else {
                        that.update()
                    }
                } else if (e.type == 'popstate') {
                    var state = e.originalEvent.state || {}
                    _path = state.path || window.location.pathname.replace(/^\//, '')
                }
                if (_path != oldpath) that.update()
            },
            update: function () {
                var dt = 'fast'
                if (_path === null) {
                    // this is the original page load. don't animate anything just jump
                    // to the proper state
                    _path = window.location.pathname.replace(/^\//, '')
                    dt = 0
                    dom.find('p').css('opacity', 0).show().fadeTo('slow', 1)
                }

                switch (_path) {
                    case '':
                    case '/':
                        //dom.find('p').text('a graph visualization library using web workers and jQuery')
                        dom.find('> a').removeClass('active').attr('href', '#')

                        $('#docs').fadeTo('fast', 0, function () {
                            $(this).hide()
                            $(that).trigger({ type: 'mode', mode: 'visible', dt: dt })
                        })
                        document.title = "pluto"
                        break

                    case 'introduction':
                    case 'reference':
                        $(that).trigger({ type: 'mode', mode: 'hidden', dt: dt })
                        dom.find('> p').text(_path)
                        dom.find('> a').addClass('active').attr('href', '#')
                        $('#docs').stop(true).css({ opacity: 0 }).show().delay(333).fadeTo('fast', 1)

                        $('#docs').find(">div").hide()
                        $('#docs').find('#' + _path).show()
                        document.title = "arbor.js » " + _path
                        break
                }

            }
        }
        return that
    }

    $(document).ready(function () {
        var CLR = {
            branch: "#b2b19d",
            code: "orange",
            doc: "#922E00",
            demo: "#a7af00"
        }

        Object.getPrototypeOf(document.createElement('canvas').getContext('2d')).fillRectR =
        function (x, y, w, h, r) {
            if (typeof r === "undefined") {
                r = 5;
            }
            this.beginPath();
            this.moveTo(x + r, y);
            this.lineTo(x + w - r, y);
            this.quadraticCurveTo(x + w, y, x + w, y + r);
            this.lineTo(x + w, y + h - r);
            this.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
            this.lineTo(x + r, y + h);
            this.quadraticCurveTo(x, y + h, x, y + h - r);
            this.lineTo(x, y + r);
            this.quadraticCurveTo(x, y, x + r, y);
            this.closePath();
            this.fill();
        };


        var theUI = {
            nodes: { user1: { color: "red", shape: "dot", alpha: 1 },
                user2: { color: "red", shape: "dot", alpha: 1 },
                user3: { color: "red", shape: "dot", alpha: 1 },
                user4: { color: "red", shape: "dot", alpha: 1 },
                user5: { color: "red", shape: "dot", alpha: 1 },
                user6: { color: "red", shape: "dot", alpha: 1 },
                name1: { color: CLR.doc, alpha: 0 },
                name2: { color: CLR.doc, alpha: 0 },
                name3: { color: CLR.doc, alpha: 0 },
                name4: { color: CLR.doc, alpha: 0 },
                name5: { color: CLR.doc, alpha: 0 },
                name6: { color: CLR.doc, alpha: 0 }


                //demos: { color: CLR.branch, shape: "dot", alpha: 1 },
                //  halfviz: { color: CLR.demo, alpha: 0, link: '/halfviz' },
                //  atlas: { color: CLR.demo, alpha: 0, link: '/atlas' },
                //  echolalia: { color: CLR.demo, alpha: 0, link: '/echolalia' },

                //  user2: { color: CLR.branch, shape: "dot", alpha: 1 },
                //  reference: { color: CLR.doc, alpha: 0, link: '#reference' },
                // location: { color: CLR.doc, alpha: 0, link: '#introduction' },

                //  code: { color: CLR.branch, shape: "dot", alpha: 1 },
                //  ".zip": { color: CLR.code, alpha: 0, link: '/js/dist/arbor-v0.92.zip' },
                //   ".tar.gz": { color: CLR.code, alpha: 0, link: '/js/dist/arbor-v0.92.tar.gz' }
            },
            edges: {
                user1: {
                    user2: {}, name1: {}
                },
                user2: {
                    user3: {}, name2: {}
                },
                user3: {
                    user4: {}, name3: {}
                },
                user4: {
                    user5: {}, name4: {}
                },
                user5: {
                    user6: {}, name5: {}
                },
                user6: {
                    name6: {}
                },
                
            }
        }


        var sys = arbor.ParticleSystem()
        sys.parameters({ stiffness: 900, repulsion: 2000, gravity: true, dt: 0.015 })
        sys.renderer = Renderer("#sitemap")
        sys.graft(theUI)

        var nav = Nav("#nav")
        $(sys.renderer).bind('navigate', nav.navigate)
        $(nav).bind('mode', sys.renderer.switchMode)
        nav.init()
    })
})(this.jQuery)